/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cc.altius.dao.impl;

import cc.altius.dao.MessageDao;
import cc.altius.domain.CustomUserDetails;
import cc.altius.model.User;
import cc.altius.model.Message;
import cc.altius.utils.DateUtils;
import java.util.Date;
import java.util.List;
import java.util.Map;
import javax.sql.DataSource;
import org.hibernate.Query;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

/**
 *
 * @author mudassar
 */
@Repository("MessageDao")
public class MessageDaoImpl implements MessageDao {

    private JdbcTemplate jdbcTemplate;
    private DataSource dataSource;
    private SessionFactory sessionFactory;
    private HibernateTemplate hibernateTemplate;
    Session session;
    Query query;

    @Autowired
    public void setDataSource(DataSource dataSource) {
        this.dataSource = dataSource;
        this.jdbcTemplate = new JdbcTemplate(dataSource);
    }

    @Autowired
    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
        this.hibernateTemplate = new HibernateTemplate(sessionFactory);
    }

    
    @Override
    @Transactional
    public int addMessage(Message message, String selectedCustomerIds) {
        int count = 0;
        int curUser = ((CustomUserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getUserId();
        Date curDate = DateUtils.getCurrentDateObject(DateUtils.IST);

        session = this.hibernateTemplate.getSessionFactory().getCurrentSession();
        if (!selectedCustomerIds.equals("")) {
            String arrselectedParameters[] = selectedCustomerIds.split(",");
            int intarray[] = new int[arrselectedParameters.length];
            System.out.println("intarray[] :" + intarray.length);
            for (int i = 0; i < arrselectedParameters.length; i++) {
                System.out.println("i :" + i);
                intarray[i] = Integer.parseInt(arrselectedParameters[i]);
                Message message1 = new Message();
                message1.setSentTo(new User(intarray[i]));
                message1.setSentBy(new User(curUser));
                message1.setSentOn(curDate);
                message1.setMessageSubject(message.getMessageSubject());
                message1.setMessageBody(message.getMessageBody());

                hibernateTemplate.save(message1);
                count++;
            }
            System.out.println("count :" + count);
        }
        return count;
    }

    @Override
    @Transactional
    public List<Map<String, Object>> getMessageList(int sentTo, String startDate, String stopDate, int sentBy) {
       List<Map<String, Object>> messages = null;
        String hql = " SELECT new map("
                + " msg.messageId as messageId,"
                + " msg.messageSubject as messageSubject,"
                + " msg.messageBody as messageBody,"
                + " msg.sentOn as sentOn,"
                + " msg.readDate as readDate,"
                + " sb.username as sentBy,"
                + " to.username as username)"
                + " from Message msg"
                + " left join msg.sentTo as to "
                + " left join msg.sentBy as sb  "
                + " where to.userId='" + sentTo + "' and msg.sentOn >='" + startDate + "' and msg.sentOn <='" + stopDate + "'";
        if (sentBy != 0) {
            hql += " and sb.userId='" + sentBy + "'";
        }
        hql += " ORDER by msg.sentOn DESC";
        messages = this.hibernateTemplate.find(hql);
        return messages;
    }

    @Override
    @Transactional
    public int getMessageCountByUserId(int userId) {
        String sql = "SELECT COUNT(*) FROM message LEFT JOIN `user` ON user.`USER_ID`=message.`SENT_TO` WHERE message.`SENT_TO`=?";
//        String hql = " SELECT new map(count(*)) "
//                + " from Message as msg"
//                + " left join msg.sentTo as to"
//                + " where to.userId=" + userId;
        Object params[] = new Object[]{userId};
        int rowsFound = this.jdbcTemplate.queryForInt(sql, params);
        if (rowsFound > 0) {
            return rowsFound;
        } else {
            return 0;
        }
    }

    @Override
    public int getunReadMessageCountForCurUser(int userId) {
        String sql = "SELECT COUNT(*) FROM message LEFT JOIN `user` ON user.`USER_ID`=message.`SENT_TO` WHERE message.`READ_DATE` IS NULL AND message.`SENT_TO`=?";
        Object params[] = new Object[]{userId};
        int totalUnread = this.jdbcTemplate.queryForInt(sql, params);
        if (totalUnread > 0) {
            return totalUnread;
        } else {
            return 0;
        }
    }

    @Override
    @Transactional
    public Message getMessageDetails(int messageId) {
        session = this.hibernateTemplate.getSessionFactory().getCurrentSession();
        String hql=" FROM Message msg "
                + " WHERE msg.messageId = :messageId ";
        query=session.createQuery(hql);
        query.setParameter("messageId", messageId);
        Message message =(Message)query.uniqueResult();
        session.refresh(message);
        return message;
    }

    @Override
    @Transactional
    public void updateStatus(int messageId) {
        
        session = this.hibernateTemplate.getSessionFactory().getCurrentSession();
        Date curDate = DateUtils.getCurrentDateObject(DateUtils.IST);
        String hql=" UPDATE Message msg set msg.readDate = :readDate"
                + " WHERE msg.messageId = :messageId and msg.readDate is null";
        query=session.createQuery(hql);
        query.setParameter("readDate", curDate);
        query.setParameter("messageId", messageId);
        query.executeUpdate();
    }
}
